package v1

import (
	"net/http"
	"strconv"

	"zhihu-api/models"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// 创建话题请求
type CreateTopicRequest struct {
	Name         string `json:"name" binding:"required,min=2,max=50"`
	Introduction string `json:"introduction"`
	Avatar       string `json:"avatar"`
}

// 创建话题
func CreateTopic(c *gin.Context) {
	var req CreateTopicRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 检查话题名称是否已存在
	var existingTopic models.Topic
	if err := models.DB.Where("name = ?", req.Name).First(&existingTopic).Error; err == nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "话题名称已存在"})
		return
	}

	// 创建新话题
	topic := models.Topic{
		Name:         req.Name,
		Introduction: req.Introduction,
		Avatar:       req.Avatar,
	}

	if err := models.DB.Create(&topic).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "创建话题失败"})
		return
	}

	c.JSON(http.StatusCreated, topic)
}

// 获取话题列表
func ListTopics(c *gin.Context) {
	var topics []models.Topic
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	limit, _ := strconv.Atoi(c.DefaultQuery("per_page", "10"))
	offset := (page - 1) * limit

	if err := models.DB.Limit(limit).Offset(offset).Find(&topics).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取话题列表失败"})
		return
	}

	c.JSON(http.StatusOK, topics)
}

// 获取话题详情
func GetTopic(c *gin.Context) {
	id := c.Param("id")
	var topic models.Topic

	if err := models.DB.First(&topic, id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "话题不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取话题失败"})
		return
	}

	c.JSON(http.StatusOK, topic)
}

// 更新话题请求
type UpdateTopicRequest struct {
	Name         string `json:"name"`
	Introduction string `json:"introduction"`
	Avatar       string `json:"avatar"`
}

// 更新话题
func UpdateTopic(c *gin.Context) {
	id := c.Param("id")

	var req UpdateTopicRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 查找话题
	var topic models.Topic
	if err := models.DB.First(&topic, id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "话题不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取话题失败"})
		return
	}

	// 检查名称是否重复
	if req.Name != "" && req.Name != topic.Name {
		var existingTopic models.Topic
		if err := models.DB.Where("name = ?", req.Name).First(&existingTopic).Error; err == nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "话题名称已存在"})
			return
		}
	}

	// 更新话题信息
	updates := make(map[string]interface{})
	if req.Name != "" {
		updates["name"] = req.Name
	}
	if req.Introduction != "" {
		updates["introduction"] = req.Introduction
	}
	if req.Avatar != "" {
		updates["avatar"] = req.Avatar
	}

	if err := models.DB.Model(&topic).Updates(updates).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新话题失败"})
		return
	}

	// 返回更新后的话题
	if err := models.DB.First(&topic, id).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取更新后的话题失败"})
		return
	}

	c.JSON(http.StatusOK, topic)
}

// 关注话题
func FollowTopic(c *gin.Context) {
	id := c.Param("id")
	userID := c.MustGet("userID").(uint)
	idUint, _ := strconv.ParseUint(id, 10, 32)

	// 检查话题是否存在
	var topic models.Topic
	if err := models.DB.First(&topic, id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "话题不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取话题失败"})
		return
	}

	// 检查是否已关注
	var count int64
	models.DB.Model(&models.UserFollowingTopic{}).Where("user_id = ? AND topic_id = ?", userID, idUint).Count(&count)
	if count > 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "已经关注该话题"})
		return
	}

	// 创建关注关系
	following := models.UserFollowingTopic{
		UserID:  userID,
		TopicID: uint(idUint),
	}

	tx := models.DB.Begin()
	if err := tx.Create(&following).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "关注话题失败"})
		return
	}

	// 更新话题的关注者数量
	if err := tx.Model(&models.Topic{}).Where("id = ?", idUint).Update("follower_count", gorm.Expr("follower_count + ?", 1)).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新话题关注者数量失败"})
		return
	}

	tx.Commit()
	c.JSON(http.StatusOK, gin.H{"message": "关注话题成功"})
}

// 取消关注话题
func UnfollowTopic(c *gin.Context) {
	id := c.Param("id")
	userID := c.MustGet("userID").(uint)
	idUint, _ := strconv.ParseUint(id, 10, 32)

	// 检查是否已关注
	var count int64
	models.DB.Model(&models.UserFollowingTopic{}).Where("user_id = ? AND topic_id = ?", userID, idUint).Count(&count)
	if count == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "未关注该话题"})
		return
	}

	tx := models.DB.Begin()
	// 删除关注关系
	if err := tx.Where("user_id = ? AND topic_id = ?", userID, idUint).Delete(&models.UserFollowingTopic{}).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "取消关注话题失败"})
		return
	}

	// 更新话题的关注者数量
	if err := tx.Model(&models.Topic{}).Where("id = ?", idUint).Update("follower_count", gorm.Expr("follower_count - ?", 1)).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新话题关注者数量失败"})
		return
	}

	tx.Commit()
	c.JSON(http.StatusOK, gin.H{"message": "取消关注话题成功"})
}

// 获取话题的关注者列表
func GetTopicFollowers(c *gin.Context) {
	id := c.Param("id")
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	limit, _ := strconv.Atoi(c.DefaultQuery("per_page", "10"))
	offset := (page - 1) * limit

	var followers []models.User
	if err := models.DB.Joins("JOIN user_following_topics ON users.id = user_following_topics.user_id").
		Where("user_following_topics.topic_id = ?", id).
		Limit(limit).Offset(offset).Find(&followers).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取话题关注者列表失败"})
		return
	}

	c.JSON(http.StatusOK, followers)
}
